package cn.mw.cmdb.controller;

import cn.mw.cmdb.entity.DataSourceGroupInfo;
import cn.mw.cmdb.entity.DataSourceInfo;
import cn.mw.cmdb.param.DataSourceSyncResultQueryParam;
import cn.mw.cmdb.service.DataSourceGroupInfoService;
import cn.mw.cmdb.service.DataSourceService;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.api.common.BaseApiService;
import cn.mw.microMonitorCommon.api.common.ResponseBase;
import cn.mw.microMonitorCommon.constants.ZabbixApiConstants;
import cn.mw.microMonitorCommon.entity.cmdb.DataSourceFilterTypeConfig;
import cn.mw.microMonitorCommon.entity.zabbix.*;
import cn.mw.microMonitorCommon.enums.DataSourceFilterTypeEnum;
import cn.mw.microMonitorCommon.enums.EngineTypeEnum;
import cn.mw.microMonitorCommon.enums.ZabbixInventoryEnum;
import cn.mw.microMonitorCommon.enums.ZabbixPropertyTypeEnum;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RequestMapping("/datasource")
@Controller
@Tag(name = "数据源")
@Slf4j
public class DatasourceController extends BaseApiService {

    @Autowired
    private DataSourceService dataSourceService;

    @Autowired
    private DataSourceGroupInfoService dataSourceGroupService;

    @Autowired
    private MessageSource messageSource;

    @DubboReference(check = false, timeout = 120000, mock = "true")
    private ZabbixDubboService zabbixDubboService;

    @PostMapping("/addOrUpdateDataSource")
    @ResponseBody
    @Operation(summary = "新增或修改数据源")
    public ResponseBase addOrUpdateDataSource(@RequestBody DataSourceInfo param) throws Exception {
        boolean isAdd = StringUtils.isBlank(param.getId());
        dataSourceService.addOrUpdateDataSource(param);
        if (isAdd) {
            return setResultSuccess(messageSource.getMessage("add-success", null, LocaleContextHolder.getLocale()));
        } else {
            return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
        }
    }

    @PostMapping("/deleteDataSource")
    @ResponseBody
    @Operation(summary = "删除数据源")
    public ResponseBase deleteDataSource(@RequestBody List<String> param) throws Exception {
        dataSourceService.deleteDataSource(param);
        return setResultSuccess(messageSource.getMessage("del-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/getDataSourceList")
    @ResponseBody
    @Operation(summary = "查询数据源列表")
    public ResponseBase getDataSourceList(@RequestBody SearchParam param) throws Exception {
        return setResultSuccess(dataSourceService.getDataSourceList(param));
    }

    @PostMapping("/syncByDataSourceIds")
    @ResponseBody
    @Operation(summary = "根据数据源Id立即同步")
    public ResponseBase syncByDataSourceIds(@RequestBody List<String> dataSourceIds) throws Exception {
        return setResultSuccess(dataSourceService.syncByDataSourceIds(dataSourceIds));
    }

    @PostMapping("/getSyncResultByDataSourceId")
    @ResponseBody
    @Operation(summary = "获取数据源同步历史")
    public ResponseBase getSyncResultByDataSourceId(@RequestBody DataSourceSyncResultQueryParam searchParam) throws Exception {
        return setResultSuccess(dataSourceService.getSyncResultByDataSourceId(searchParam));
    }

    @PostMapping("/getSyncInstanceByTaskId")
    @ResponseBody
    @Operation(summary = "获取同步任务详情")
    public ResponseBase getSyncInstanceByTaskId(@RequestBody DataSourceSyncResultQueryParam searchParam) throws Exception {
        return setResultSuccess(dataSourceService.getSyncInstanceByTaskId(searchParam));
    }

    @PostMapping("/getDataSourceTableHeader")
    @ResponseBody
    @Operation(summary = "获取同步结果表头")
    public ResponseBase getDataSourceTableHeader(String dataSourceId) throws Exception {
        return setResultSuccess(dataSourceService.getDataSourceTableHeader(dataSourceId));
    }

    @GetMapping("/getHostGroupDrop")
    @ResponseBody
    @Operation(summary = "查询主机群组列表")
    public ResponseBase getHostGroupDrop(Integer engineId) throws Exception {
        MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_HOST_GROUP, engineId);
        List<MWZabbixHostGroupVo> hostGroupVoList = new ArrayList<>();
        if (mwZabbixAPIResult != null && mwZabbixAPIResult.isSuccess()) {
            hostGroupVoList = JSONArray.parseArray(JSON.toJSONString(mwZabbixAPIResult.data), MWZabbixHostGroupVo.class);
            // 移除没有主机的群组
            hostGroupVoList = hostGroupVoList.stream().filter(item -> CollectionUtils.isNotEmpty(item.getHosts())).toList();
            hostGroupVoList.forEach(item -> {
                item.setHosts(null);
            });
        }
        return setResultSuccess(hostGroupVoList);
    }

    @GetMapping("/getTemplateDrop")
    @ResponseBody
    @Operation(summary = "查询模板列表下拉")
    public ResponseBase getTemplateDrop(Integer engineId) throws Exception {
        MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.TEMPLATE_GET, engineId, null, false);
        List<MWZabbixTemplateVo> mwZabbixTemplateVoList = new ArrayList<>();
        if (mwZabbixAPIResult != null && mwZabbixAPIResult.isSuccess()) {
            mwZabbixTemplateVoList = JSONArray.parseArray(JSON.toJSONString(mwZabbixAPIResult.data), MWZabbixTemplateVo.class);
        }
        return setResultSuccess(mwZabbixTemplateVoList);
    }

    @GetMapping("/getPropertyDrop")
    @ResponseBody
    @Operation(summary = "查询属性值下拉列表")
    public ResponseBase getPropertyDrop(Integer engineId, String groupId, String templateId) throws Exception {
        List<MWZabbixPropertyVo> mwZabbixPropertyVoList = new ArrayList<>();
        for (ZabbixInventoryEnum zabbixInventoryEnum : ZabbixInventoryEnum.values()) {
            MWZabbixPropertyVo mwZabbixPropertyVo = new MWZabbixPropertyVo();
            mwZabbixPropertyVo.setKey(zabbixInventoryEnum.getKey());
            mwZabbixPropertyVo.setDesc(zabbixInventoryEnum.getDesc());
            mwZabbixPropertyVo.setType(ZabbixPropertyTypeEnum.Inventory);
            mwZabbixPropertyVoList.add(mwZabbixPropertyVo);
        }

        // 按照监控项填写属性
        if (StringUtils.isNotEmpty(templateId)) {
            MWZabbixAPIResult mwZabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.ITEM_GET_BY_TEMPLATE_ID, engineId, templateId);
            List<MWZabbixTemplateVo> zabbixTemplateVoList;
            if (mwZabbixAPIResult.isSuccess()) {
                zabbixTemplateVoList = JSONArray.parseArray(JSON.toJSONString(mwZabbixAPIResult.data), MWZabbixTemplateVo.class);
                zabbixTemplateVoList.forEach(item -> {
                    for (MWZabbixItemVo mwZabbixItemVo : item.getItems()) {
                        MWZabbixPropertyVo mwZabbixPropertyVo = new MWZabbixPropertyVo();
                        mwZabbixPropertyVo.setKey(mwZabbixItemVo.getKey_());
                        mwZabbixPropertyVo.setDesc(mwZabbixItemVo.getName());
                        mwZabbixPropertyVo.setType(ZabbixPropertyTypeEnum.Item);
                        mwZabbixPropertyVoList.add(mwZabbixPropertyVo);
                    }
                });
            }
        }
        // 按照资产记录填写属性
        return setResultSuccess(mwZabbixPropertyVoList);
    }

    @GetMapping("/getDataSourceFilterType")
    @ResponseBody
    @Operation(summary = "查询过滤类型配置")
    public ResponseBase getDataSourceFilterType(EngineTypeEnum engineType) throws Exception {
        List<DataSourceFilterTypeConfig> dataSourceFilterTypeConfigList = new ArrayList<>();
        DataSourceFilterTypeConfig dataSourceFilterTypeConfig;
        for (DataSourceFilterTypeEnum dataSourceFilterTypeEnum : DataSourceFilterTypeEnum.values()) {
            if (CollectionUtils.isNotEmpty(dataSourceFilterTypeEnum.getEngineTypeList()) && dataSourceFilterTypeEnum.getEngineTypeList().contains(engineType)) {
                dataSourceFilterTypeConfig = new DataSourceFilterTypeConfig();
                dataSourceFilterTypeConfig.setFilterTypeName(dataSourceFilterTypeEnum.name());
                dataSourceFilterTypeConfig.setFilterTypeDesc(dataSourceFilterTypeEnum.getFilterTypeDesc());
                dataSourceFilterTypeConfig.setPropertyType(dataSourceFilterTypeEnum.getPropertyType());
                dataSourceFilterTypeConfig.setValueType(dataSourceFilterTypeEnum.getValueType());
                dataSourceFilterTypeConfig.setConditions(dataSourceFilterTypeEnum.getConditions());
                dataSourceFilterTypeConfigList.add(dataSourceFilterTypeConfig);
            }
        }
        return setResultSuccess(dataSourceFilterTypeConfigList);
    }

    @PostMapping("/addOrUpdateDataSourceGroupInfo")
    @ResponseBody
    @Operation(summary = "新增或编辑分组")
    public ResponseBase addOrUpdateDataSourceGroupInfo(@RequestBody DataSourceGroupInfo dataSourceGroupInfo) throws Exception {
        return setResultSuccess(dataSourceGroupService.addOrUpdateDataSourceGroupInfo(dataSourceGroupInfo));
    }

    @GetMapping("/deleteDataSourceGroupInfo")
    @ResponseBody
    @Operation(summary = "删除分组")
    public ResponseBase deleteDataSourceGroupInfo(String id) throws Exception {
        return setResultSuccess(dataSourceGroupService.deleteDataSourceGroupInfo(id));
    }

    @PostMapping("/getGroupTree")
    @ResponseBody
    @Operation(summary = "分组树形结构")
    public ResponseBase getGroupTree() throws Exception {
        return setResultSuccess(dataSourceGroupService.getGroupTree());
    }

    @GetMapping("/getGroupInfo")
    @ResponseBody
    @Operation(summary = "查询分组信息")
    public ResponseBase getGroupInfo(String id) throws Exception {
        return setResultSuccess(dataSourceGroupService.getGroupInfo(id));
    }
}
